package com.chart.web.controller.doubao;
import com.chart.common.core.domain.AjaxResult;
import com.chart.common.core.domain.entity.SysUser;
import com.chart.common.core.domain.entity.UserCoinLog;
import com.chart.common.utils.SecurityUtils;
import com.chart.common.utils.StringUtils;
import com.chart.common.utils.uuid.IdUtils;
import com.chart.framework.config.OssConfig;
import com.chart.system.service.ISysUserService;
import com.chart.system.service.IUserCoinLogsService;
import com.chart.web.controller.chart.dto.DouBaoDTO;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.CannedAccessControlList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.util.*;


@RestController
@RequestMapping("/doubao/photo/ai")
public class DoubaoPhotoAiController {


    private static final Logger log = LoggerFactory.getLogger(DoubaoPhotoAiController.class);

    @Value("${doubao.api.url}")
    private String doubaoApiUrl;

    @Value("${doubao.api.key}")
    private String doubaoApiKey;

    @Value("${doubao.api.model}")
    private String model;

    @Value("${aliyun.oss.endpoint}")
    private String endpoint;

    @Value("${aliyun.oss.accessKeyId}")
    private String accessKeyId;

    @Value("${aliyun.oss.accessKeySecret}")
    private String accessKeySecret;

    @Value("${aliyun.oss.bucketName}")
    private String bucketName;

    @Autowired
    private OssConfig ossConfig;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private IUserCoinLogsService userCoinLogsService;

    private final RestTemplate restTemplate = new RestTemplate();

    @PostMapping("/doubaoAiBefter")
    public AjaxResult doubaoAi(@RequestParam("file") MultipartFile file, @RequestParam("detail") String detail) {

        try {
            byte[] imageBytes = file.getBytes();
            ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes);
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            try {
                String uniqueFileName = "uploads/" + System.currentTimeMillis() + "_" + file.getOriginalFilename();
                ossClient.putObject(bucketName, uniqueFileName, inputStream);
                ossClient.setObjectAcl(bucketName, uniqueFileName, CannedAccessControlList.PublicRead);
                String imageUrl = "https://" + bucketName + "." + endpoint + "/" + uniqueFileName;
                log.info("文件url: {}", imageUrl);
                Map<String, Object> requestBody = createRequestBody(detail, imageUrl);
                return sendRequestToApi(requestBody);

            } finally {

                if (ossClient != null) {
                    ossClient.shutdown();
                }
            }
        } catch (IOException e) {
            log.error("上传错误", e);
            return AjaxResult.error("获取url失败 " + e.getMessage());
        } catch (Exception e) {
            log.error("上传错误: ", e);
            return AjaxResult.error(560,"错误，请重试 " + e.getMessage());
        }
    }

    private Map<String, Object> createRequestBody(String detail, String imageUrl) {
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("model", model);

        List<Map<String, Object>> messages = new ArrayList<>();
        Map<String, Object> message = new HashMap<>();
        message.put("role", "user");

        List<Map<String, String>> content = new ArrayList<>();
        Map<String, String> textContent = new HashMap<>();
        textContent.put("type", "text");
        textContent.put("text", detail);

        Map<String, String> imageContent = new HashMap<>();
        imageContent.put("type", "image_url");
        imageContent.put("image_url", imageUrl);

        content.add(textContent);
        content.add(imageContent);

        message.put("content", content);
        messages.add(message);

        requestBody.put("messages", messages);
        return requestBody;
    }

    private AjaxResult sendRequestToApi(Map<String, Object> requestBody) {
        try {

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("Authorization", "Bearer " + doubaoApiKey);


            HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
            ResponseEntity<String> response = restTemplate.exchange(
                    doubaoApiUrl,
                    HttpMethod.POST,
                    requestEntity,
                    String.class
            );

            String body = response.getBody();

            ObjectMapper objectMapper = new ObjectMapper();
            // 将body字符串解析为Map以便于AjaxResult.success方法处理
            Map<String, Object> jsonResponse = objectMapper.readValue(body, Map.class);
            return AjaxResult.success(jsonResponse);


        } catch (Exception e) {
            log.error("Error sending request to API: ", e);
            return AjaxResult.error("Failed to send request to API: " + e.getMessage());
        }
    }


    /**
     * 解码Base64字符串并移除前缀
     *
     * @param base64Image Base64编码的图像字符串
     * @return 解码后的字节数组
     * @throws IllegalArgumentException 如果Base64编码无效
     */
    private byte[] decodeBase64Image(String base64Image) {
        if (base64Image.startsWith("data:image/png;base64,")) {
            base64Image = base64Image.substring("data:image/png;base64,".length());
        }
        return Base64.getDecoder().decode(base64Image);
    }



    // 生成 MD5 值
    private String generateMD5(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(input.getBytes());
            byte[] digest = md.digest();
            StringBuilder sb = new StringBuilder();
            for (byte b : digest) {
                sb.append(String.format("%02x", b)); // 转换为十六进制字符串
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            log.error("MD5 生成失败", e);
            return "";
        }
    }




    /**
     * 豆包上传base64
     * @param
     * @param
     * @return
     */

//    @PostMapping("/doubaoAi")
//    public AjaxResult doubaoAi(@RequestBody DouBaoDTO douBaoDTO) {
//        if(StringUtils.isEmpty(douBaoDTO.getDetail())){
//            return  AjaxResult.error(400,"detail为空请重试");
//        }
//        if(StringUtils.isEmpty(douBaoDTO.getFile())){
//            return  AjaxResult.error(400,"file为空请重试");
//        }
//        String detail = douBaoDTO.getDetail();
//        String chartCover = douBaoDTO.getFile();
//
//
//        Long userId = SecurityUtils.getUserId();
//        SysUser sysUser = userService.queryById(userId);
//        Integer isVip = sysUser.getIsVip();
//        if (isVip == 0) { //不是VIP
//
//        }
//
//
//        try {
//            // 解码 Base64 图表封面
//            byte[] decodedBytes = decodeBase64Image(chartCover);
//            String name = IdUtils.generateRandomNumber();
//            // 生成随机数字并进行 MD5 加密
//            String md5FileName = generateMD5(name);
//            ByteArrayInputStream inputStream = new ByteArrayInputStream(decodedBytes);
//            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
//            try {
//                String uniqueFileName = "uploadsDouBao/" + System.currentTimeMillis() + "_" + md5FileName;
//                ossClient.putObject(bucketName, uniqueFileName, inputStream);
//                ossClient.setObjectAcl(bucketName, uniqueFileName, CannedAccessControlList.PublicRead);
//                String imageUrl = "https://" + bucketName + "." + endpoint + "/" + uniqueFileName;
//                log.info("文件url: {}", imageUrl);
//                Map<String, Object> requestBody = createRequestBody(detail, imageUrl);
//                return sendRequestToApi(requestBody);
//            } finally {
//                if (ossClient != null) {
//                    ossClient.shutdown();
//                }
//            }
//        } catch (Exception e) {
//            log.error("上传错误: ", e);
//            return AjaxResult.error(560,"错误，请重试 " + e.getMessage());
//        }
//    }
//



    @PostMapping("/deductCoins")
    public AjaxResult deductAiCoins(Integer coins, String type) {
        Long userId = SecurityUtils.getUserId();
        Integer totalCoins = userCoinLogsService.getTotalCoinsByUserId(userId);
        if (coins == 0) {
         // 构建返回数据
            Map<String, Object> data = new HashMap<>();
            data.put("deductAiCoins", coins);
            data.put("totalCoins", totalCoins);
            data.put("deductStatus", 0);//没有扣除
            return AjaxResult.success("操作成功", data);
        }
        if (totalCoins - coins < 0) {
       // 构建返回数据
            Map<String, Object> data = new HashMap<>();
            data.put("deductAiCoins", 0);
            data.put("totalCoins", totalCoins);
            data.put("deductStatus", 1);//扣除失败
            return AjaxResult.success("金币不足", data);
        } else {
            // 扣除金币
            UserCoinLog log = new UserCoinLog();
            log.setUserId(userId);
            log.setAction(type);
            log.setCoins(-coins); // 扣除金币数，使用负值表示扣除
            log.setCreatedAt(LocalDateTime.now());
            userCoinLogsService.save(log);
          // 构建返回数据
            Map<String, Object> data = new HashMap<>();
            data.put("deductAiCoins", coins);
            data.put("totalCoins", totalCoins);
            data.put("deductStatus", 0);
            return AjaxResult.success("操作成功", data);
        }

    }


    /**
     * 豆包AI 新接口
     * @param douBaoDTO
     * @return
     */

   @PostMapping("/doubaoAi")
   @Transactional
    public AjaxResult KdoubaoAiNB(@RequestBody DouBaoDTO douBaoDTO) {
        if (StringUtils.isEmpty(douBaoDTO.getDetail())) {
            return AjaxResult.error(400, "detail为空请重试");
        }
        if (StringUtils.isEmpty(douBaoDTO.getFile())) {
            return AjaxResult.error(400, "file为空请重试");
        }
        String detail = douBaoDTO.getDetail();
        String chartCover = douBaoDTO.getFile();

        Long userId = SecurityUtils.getUserId();
        SysUser sysUser = userService.queryById(userId);
        Integer isVip = sysUser.getIsVip();
        Integer totalCoins = userCoinLogsService.getTotalCoinsByUserId(userId);
        //  不是VIP
        if (isVip == 0) {
            Integer coins = 1;//解图
            String type = "DOUBAOPHOTO";

            if (totalCoins - coins < 0) {          //金币不足
                // 构建返回数据
                Map<String, Object> data = new HashMap<>();
                data.put("deductAiCoins", 0);
                data.put("totalCoins", totalCoins);
                data.put("deductStatus", 0);//扣除失败

                HashMap<Object, Object> map = new HashMap<>();
                map.put("jsonResponse","");
                map.put("data",data);

                return AjaxResult.success("金币不足", map);

            }else {              //金币充足

                // 扣除金币
                UserCoinLog log = new UserCoinLog();
                log.setUserId(userId);
                log.setAction(type);
                log.setCoins(-coins); // 扣除金币数，使用负值表示扣除
                log.setCreatedAt(LocalDateTime.now());
                userCoinLogsService.save(log);


                Integer totalCoins1 = userCoinLogsService.getTotalCoinsByUserId(userId);
                Map<String, Object> data = new HashMap<>();
                data.put("deductAiCoins", coins);
                data.put("totalCoins", totalCoins1);
                data.put("deductStatus", 1);//扣除成功


                OSS ossClient = null;
                String uniqueFileName = null; // 用于后续删除文件

                try {
                    // 解码 Base64 图表封面
                    byte[] decodedBytes = decodeBase64Image(chartCover);
                    String name = IdUtils.generateRandomNumber();
                    // 生成随机数字并进行 MD5 加密
                    String md5FileName = generateMD5(name);
                    ByteArrayInputStream inputStream = new ByteArrayInputStream(decodedBytes);

                    ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
                    uniqueFileName = "uploadsDouBao/" + System.currentTimeMillis() + "_" + md5FileName;
                    ossClient.putObject(bucketName, uniqueFileName, inputStream);
                    ossClient.setObjectAcl(bucketName, uniqueFileName, CannedAccessControlList.PublicRead);
                    String imageUrl = "https://" + bucketName + "." + endpoint + "/" + uniqueFileName;


                    Map<String, Object> requestBody = createRequestBody(detail, imageUrl);
                    //AjaxResult apiResponse = sendRequestToApi(requestBody);
                    System.out.println("--------------------------------------");
                    HttpHeaders headers = new HttpHeaders();
                    headers.setContentType(MediaType.APPLICATION_JSON);
                    headers.set("Authorization", "Bearer " + doubaoApiKey);


                    HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
                    ResponseEntity<String> response = restTemplate.exchange(
                            doubaoApiUrl,
                            HttpMethod.POST,
                            requestEntity,
                            String.class
                    );

                    String body = response.getBody();

                    ObjectMapper objectMapper = new ObjectMapper();
                    // 将body字符串解析为Map以便于AjaxResult.success方法处理
                    Map<String, Object> jsonResponse = objectMapper.readValue(body, Map.class);



                    System.out.println("--------------------------------------");


                //删除OSS上的图片
                    deleteObjectFromOss(ossClient, bucketName, uniqueFileName);


                    HashMap<Object, Object> map = new HashMap<>();
                    map.put("jsonResponse",jsonResponse);
                    map.put("data",data);


                    return  AjaxResult.success(map);
                } catch (Exception e) {
                    return AjaxResult.error(560, "错误，请重试 " + e.getMessage());
                } finally {
                    if (ossClient != null) {
                        ossClient.shutdown();
                    }
                }


            }




        }


      // VIP 直接放行

        OSS ossClient = null;
        String uniqueFileName = null; // 用于后续删除文件

        try {
            // 解码 Base64 图表封面
            byte[] decodedBytes = decodeBase64Image(chartCover);
            String name = IdUtils.generateRandomNumber();
            // 生成随机数字并进行 MD5 加密
            String md5FileName = generateMD5(name);
            ByteArrayInputStream inputStream = new ByteArrayInputStream(decodedBytes);

            ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            uniqueFileName = "uploadsDouBao/" + System.currentTimeMillis() + "_" + md5FileName;
            ossClient.putObject(bucketName, uniqueFileName, inputStream);
            ossClient.setObjectAcl(bucketName, uniqueFileName, CannedAccessControlList.PublicRead);
            String imageUrl = "https://" + bucketName + "." + endpoint + "/" + uniqueFileName;
            log.info("文件url: {}", imageUrl);

            Map<String, Object> requestBody = createRequestBody(detail, imageUrl);
            //AjaxResult apiResponse = sendRequestToApi(requestBody);
            System.out.println("--------------------------------------");
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("Authorization", "Bearer " + doubaoApiKey);


            HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
            ResponseEntity<String> response = restTemplate.exchange(
                    doubaoApiUrl,
                    HttpMethod.POST,
                    requestEntity,
                    String.class
            );

            String body = response.getBody();

            ObjectMapper objectMapper = new ObjectMapper();
            // 将body字符串解析为Map以便于AjaxResult.success方法处理
            Map<String, Object> jsonResponse = objectMapper.readValue(body, Map.class);

            //删除OSS上的图片
            deleteObjectFromOss(ossClient, bucketName, uniqueFileName);

            System.out.println("--------------------------------------");


            Map<String, Object> data = new HashMap<>();
            data.put("deductAiCoins", 0);
            data.put("totalCoins", totalCoins);
            data.put("deductStatus", 0);//扣除失败
            HashMap<Object, Object> map = new HashMap<>();
            map.put("jsonResponse",jsonResponse);
            map.put("data",data);
            return  AjaxResult.success(map);
        } catch (Exception e) {
            log.error("上传错误: ", e);
            return AjaxResult.error(560, "错误，请重试 " + e.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }






  //  @PostMapping("/doubaoAi") 测试用不能删除
    public AjaxResult doubaoAi(@RequestBody DouBaoDTO douBaoDTO) {
        if (StringUtils.isEmpty(douBaoDTO.getDetail())) {
            return AjaxResult.error(400, "detail为空请重试");
        }
        if (StringUtils.isEmpty(douBaoDTO.getFile())) {
            return AjaxResult.error(400, "file为空请重试");
        }

        String detail = douBaoDTO.getDetail();
        String chartCover = douBaoDTO.getFile();

        Long userId = SecurityUtils.getUserId();
        SysUser sysUser = userService.queryById(userId);
        Integer isVip = sysUser.getIsVip();
        if (isVip == 0) { // 不是VIP
            // 可以在此处添加非VIP用户的限制逻辑
        }

        OSS ossClient = null;
        String uniqueFileName = null; // 用于后续删除文件

        try {
            // 解码 Base64 图表封面
            byte[] decodedBytes = decodeBase64Image(chartCover);
            String name = IdUtils.generateRandomNumber();
            // 生成随机数字并进行 MD5 加密
            String md5FileName = generateMD5(name);
            ByteArrayInputStream inputStream = new ByteArrayInputStream(decodedBytes);

            ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            uniqueFileName = "uploadsDouBao/" + System.currentTimeMillis() + "_" + md5FileName;
            ossClient.putObject(bucketName, uniqueFileName, inputStream);
            ossClient.setObjectAcl(bucketName, uniqueFileName, CannedAccessControlList.PublicRead);
            String imageUrl = "https://" + bucketName + "." + endpoint + "/" + uniqueFileName;
            log.info("文件url: {}", imageUrl);

            Map<String, Object> requestBody = createRequestBody(detail, imageUrl);
            AjaxResult apiResponse = sendRequestToApi(requestBody);

            if (apiResponse.isSuccess()) {
                // 如果API调用成功，则删除OSS上的图片
                deleteObjectFromOss(ossClient, bucketName, uniqueFileName);
            }
            return apiResponse;
        } catch (Exception e) {
            log.error("上传错误: ", e);
            return AjaxResult.error(560, "错误，请重试 " + e.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }


    private void deleteObjectFromOss(OSS ossClient, String bucketName, String objectName) {
        try {
            ossClient.deleteObject(bucketName, objectName);
            log.info("已删除文件: {}", objectName);
        } catch (Exception e) {
            log.error("删除OSS文件时出错: {}", objectName, e);
        }
    }

}
